package com.kzj.domain.bk;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.kzj.common.exception.MyException;
import com.kzj.common.constant.GlobalConstant;
import com.kzj.domain.Equation;
import com.kzj.domain.Exercises;
import com.kzj.domain.bk.EquationBP3;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

public class ExercisesBP3 extends Exercises {
    /**
     * 算式存储数组
     */
    private List<EquationBP3> equationBP3List =new ArrayList<>();
    public ExercisesBP3(){};
    public ExercisesBP3(Integer number, Integer type, Integer grade){
        if(grade>6||grade<1)
            throw new MyException(GlobalConstant.GRADE_ERROR);
        if(number>100||number<1)
            throw new MyException(GlobalConstant.NUMBER_ERROR);
        int[] addLimit={30,50,100,200,500,1000};
        int[] subLimit={30,50,100,200,500,1000};
        int[] mulLimit={5,9,12,15,20,31};
        int[] divLimit={5,9,12,15,20,31};
        if(type.equals(Exercises.ADDITION))
        {
            while(equationBP3List.size()<number)
            {
                this.add(EquationBP3.generateAdditionEquation(addLimit[grade-1]));
            }
        }
        else if(type.equals(Exercises.SUBDUCTION))
        {
            while(equationBP3List.size()<number)
            {
                this.add(EquationBP3.generateSubstractEquation(subLimit[grade-1]));
            }
        }
        else if(type.equals(Exercises.MUL))
        {
            while(equationBP3List.size()<number)
            {
                this.add(EquationBP3.generateMulEquation(mulLimit[grade-1]));
            }
        }
        else if(type.equals(Exercises.DIV))
        {
            while(equationBP3List.size()<number)
            {
                this.add(EquationBP3.generateDivEquation(divLimit[grade-1]));
            }
        }
        else if(type.equals(Exercises.MIX))
        {
            while(equationBP3List.size()<number)
            {
                Random random = new Random();
                int i = random.nextInt(4);
                if(i==0)
                {
                    this.add(EquationBP3.generateAdditionEquation(addLimit[grade-1]));
                }
                else if(i==1)
                {
                    this.add(EquationBP3.generateSubstractEquation(subLimit[grade-1]));
                }
                else if(i==2)
                {
                    this.add(EquationBP3.generateMulEquation(mulLimit[grade-1]));
                }
                else if(i==3)
                {
                    this.add(EquationBP3.generateDivEquation(divLimit[grade-1]));
                }
            }
        }
        else throw new MyException(GlobalConstant.EXERCISES_TYPE_ERROR);
    }
//    public ExercisesBP(Integer number,Integer type)
//    {
//         this(number,type,100);
//    }
//    /**
//     *
//     * @param amount 初始生成算式数量
//     * @param limit 算式数值的范围
//     */
//    public ExercisesBP(Integer amount,Integer type,Integer limit){
//        if(type.equals(Exercises.MIX))
//        {
//            while(equationBPList.size()<amount)
//            {
//                this.add(EquationBP.generateEquation(limit));
//            }
//        }
//        else if(type.equals(Exercises.ADDITION))
//        {
//            while(equationBPList.size()<amount)
//            {
//                this.add(EquationBP.generateAdditionEquation(limit));
//            }
//        }
//        else if(type.equals(Exercises.SUBDUCTION))
//        {
//            while(equationBPList.size()<amount)
//            {
//                this.add(EquationBP.generateSubstractEquation(limit));
//            }
//        }
//        else {
//            throw new MyException(GlobalConstant.EXERCISES_TYPE_ERROR);
//        }
//
//    }
    public static String getTypeToString(Integer type)
    {
        if(type.equals(Exercises.ADDITION))
        {
            return GlobalConstant.EXERCISES_TYPE_ADD;
        }
        else if(type.equals(Exercises.SUBDUCTION))
        {
            return GlobalConstant.EXERCISES_TYPE_SUB;
        }
        else if(type.equals(Exercises.MUL))
        {
            return GlobalConstant.EXERCISES_TYPE_MUL;
        }
        else if(type.equals(Exercises.DIV))
        {
            return GlobalConstant.EXERCISES_TYPE_DIV;
        }
        else if(type.equals(Exercises.MIX))
        {
            return GlobalConstant.EXERCISES_TYPE_MIX;
        }
        else if(type.equals(Exercises.ERROR_SET))
        {
            return GlobalConstant.EXERCISES_TYPE_ERROR_SET;
        }
        else return GlobalConstant.EXERCISES_TYPE_UNKNOWN;
    }
    public static String getTypeAndTimingToString(Exercises exercises)
    {
        Integer type=exercises.getType();
        if(type.equals(Exercises.ADDITION))
        {
            if(exercises.getTimingTime()!=null)
                return GlobalConstant.EXERCISES_TYPE_LIMIT_ADD;
            return GlobalConstant.EXERCISES_TYPE_ADD;
        }
        else if(type.equals(Exercises.SUBDUCTION))
        {
            if(exercises.getTimingTime()!=null)
                return GlobalConstant.EXERCISES_TYPE_LIMIT_SUB;
            return GlobalConstant.EXERCISES_TYPE_SUB;
        }
        else if(type.equals(Exercises.MUL))
        {
            if(exercises.getTimingTime()!=null)
                return GlobalConstant.EXERCISES_TYPE_LIMIT_MUL;
            return GlobalConstant.EXERCISES_TYPE_MUL;
        }
        else if(type.equals(Exercises.DIV))
        {
            if(exercises.getTimingTime()!=null)
                return GlobalConstant.EXERCISES_TYPE_LIMIT_DIV;
            return GlobalConstant.EXERCISES_TYPE_DIV;
        }
        else if(type.equals(Exercises.MIX))
        {
            if(exercises.getTimingTime()!=null)
                return GlobalConstant.EXERCISES_TYPE_LIMIT_MIX;
            return GlobalConstant.EXERCISES_TYPE_MIX;
        }
        else return GlobalConstant.EXERCISES_TYPE_UNKNOWN;
    }
    public List<Equation> getEquationList(Long exercisesId)
    {
        List<Equation> collect = this.equationBP3List.stream().map(item -> {
            Equation equation = new Equation();
            long id = IdWorker.getId();
            equation.setId(id);
            equation.setExercisesId(exercisesId);
            equation.setContent(item.toString());
            equation.setAnswer(EquationBP3.calculateResult(item).toString());
            return equation;
        }).collect(Collectors.toList());
        return collect;
    }


    /**
     * 习题是否包含某个算式
     * @param obj 算式
     * @return ture: 习题已经包含该算式 false:习题不包含该算式
     */
    public boolean include(EquationBP3 obj)
    {
        boolean flag=false;
        for (EquationBP3 equationBP3 : equationBP3List) {
            if(equationBP3.equals(obj))
            {
                flag=true;
                break;
            }
        }
        return flag;
    }

    /**
     * 习题增加算式
     * @param obj 算式
     * @return ture:添加成功 false:添加失败(算式已包含或为空)
     */
    public boolean add(EquationBP3 obj)
    {
        if(obj==null||this.include(obj))
            return false;
        else{
            this.equationBP3List.add(obj);
            return true;
        }
    }

    /**
     * 习题展示
     */
    public void displayExercise()
    {
        System.out.println("---------------------------------------------------------------------");
        System.out.println("习题展示：");
        for (int i = 0; i < equationBP3List.size(); i++) {
            System.out.println("第"+(i+1)+"题  :"+ equationBP3List.toArray()[i]);
        }
        System.out.println("---------------------------------------------------------------------");
    }

    /**
     * 习题及答案展示
     */
    public void displayExerciseAndResult()
    {
        System.out.println("---------------------------------------------------------------------");
        System.out.println("习题及答案展示：");
        for (int i = 0; i < equationBP3List.size(); i++) {
            System.out.println("第"+(i+1)+"题  :"+ EquationBP3.calculateResultToString((EquationBP3) equationBP3List.toArray()[i]));
        }
        System.out.println("---------------------------------------------------------------------");
    }

    /**
     * 得到习题的算式数量
     * @return
     */
    public Integer size()
    {
        return this.equationBP3List.size();
    }

    /**
     * 得到指定序号的算式(若序号不合理则返回null)
     * @param index 序号
     * @return 指定序号的算式
     */
    public EquationBP3 get(Integer index)
    {
        if(index>=this.equationBP3List.size()||index<0)
            return null;
        return this.equationBP3List.get(index);
    }

    /**
     * 得到指定序号的元素,并将其从算式存储数值中移出(若序号不合理则返回null)
     * @param index 序号
     * @return 指定序号的算式
     */
    public EquationBP3 pop(Integer index)
    {
        EquationBP3 equationBP3 = this.get(index);
        if(equationBP3 ==null)
            return null;
        this.equationBP3List.remove((int)index);
        return equationBP3;
    }
}
